#include <SDL.h>
#include <SDL_opengl.h>

#include <slak/geom/ArcBall.h>
#include <slak/mesh/Mesh.h>
#include <slak/mesh/Material.h>
#include <slak/mesh/Prims.h>

slak::geom::ArcBall arcball;

using namespace slak::mesh;
Mesh boxMesh;

void demo_prepare_gl()
{
	glClearColor(1,1,1,1);

	glEnable(GL_LINE_SMOOTH);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	glEnable(GL_CULL_FACE);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0, 1.0, .1, 100);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	float pos[] = { 2, 2, -1 , 1}, 
	      amb[] = { 0, 0, 0, 1},
	      diff[] = { 1, 1, 1, 1},
	      spec[] = { 1, 1, 1, 1};
	glLightfv(GL_LIGHT0, GL_POSITION, pos);
	glLightfv(GL_LIGHT0, GL_AMBIENT, amb);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, diff);
	glLightfv(GL_LIGHT0, GL_SPECULAR, spec);
}

void demo_draw()
{
	slak::geom::Matrix rot_mat;

	glLoadIdentity();
	gluLookAt(1,1,-3, 0,0,0, 0,1,0);
	arcball.getMatrix(rot_mat);
	glMultMatrixf((GLfloat*)rot_mat);

	glClear(GL_COLOR_BUFFER_BIT);

	boxMesh.render();

	SDL_GL_SwapBuffers();
}

void demo_mouse_down(SDL_MouseButtonEvent * ev)
{
	arcball.clickScaled(ev->x, ev->y);
}

void demo_mouse_motion(SDL_MouseMotionEvent * ev)
{
	if (ev->state & SDL_BUTTON(1))
		arcball.dragScaled(ev->x, ev->y);
}

#include <iostream>
int loadResources(const char * fname);

int lexerGetNumLines();
int lexerGetNumChars();

int main(int argc, char * argv[])
{
#if NEVER
	// ---
	yy::parser_driver driver;
	//driver.trace_parsing = true;
	//driver.trace_scanning = true;
	driver.parse("demo-resources.sg3");
	yy::SymbolTable mesh_table = driver.class_table["mesh"];
	yy::Section mesh_section = mesh_table["Pink Shiny Box"];
	yy::Section::iterator it = mesh_section.begin();
	while(it != mesh_section.end()) {
		std::cout << (*it).first << ' ';
		yy::ArgList::iterator it2 = (*it).second.begin();
		while(it2 != (*it).second.end()) {
			std::cout << *it2 << " ";
			it2++;
		}
		std::cout << '\n';
		it++;
	}
	exit(0);
	// ---
#endif

	SDL_Init(SDL_INIT_VIDEO);

	SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
	SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
	SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
	SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
	SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 1);

	if (SDL_SetVideoMode(1024, 768, 32, SDL_OPENGL|SDL_FULLSCREEN) == NULL) {
		exit(1);
	}

	demo_prepare_gl();
	
	OglMaterial pink_shiny, pink_shiny_wire;
	pink_shiny.setDiffuse(1,0.5,0.5,1);
	pink_shiny.setAmbient(1,0.5,0.5,1);
	pink_shiny.setSpecular(1,.9,.9,1);
	pink_shiny.shininess = 128;
	pink_shiny.polygon_mode = GL_FILL;
	pink_shiny.blend = false;

	pink_shiny_wire = pink_shiny;
	pink_shiny_wire.blend = true;
	pink_shiny_wire.polygon_mode = GL_LINE;

	MultipassMaterial multi_pink;
	multi_pink.passes.push_back(&pink_shiny);
	multi_pink.passes.push_back(&pink_shiny_wire);

	boxMesh.append(&multi_pink, Prims::makeBoxPatch(0,0,0,1,1,1));

	bool ex = false;
	while(!ex) {
		SDL_Event ev;
		while(SDL_PollEvent(&ev)) {
			switch (ev.type) {
			case SDL_KEYDOWN:
				if (ev.key.keysym.sym == 27)
					ex = true;
				break;
			case SDL_MOUSEBUTTONDOWN:
				demo_mouse_down(&ev.button);
				break;
			case SDL_MOUSEMOTION:
				demo_mouse_motion(&ev.motion);
				break;
			}
		}
		demo_draw();
		SDL_Delay(10);
	}
	
	return 0;
}


